// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <pollux/expression/vector_function.h>
#include <pollux/vector/base_vector.h>

namespace kumo::pollux::functions {
    /// Helper function that prepares a string result vector and initializes it.
    /// It will use the input argToReuse vector instead of creating new one when
    /// possible. Returns true if argToReuse vector was moved to results
    ///
    /// @param resultType VARCHAR() or VARBINARY().
    bool prepareFlatResultsVector(
        VectorPtr &result,
        const SelectivityVector &rows,
        exec::EvalCtx &context,
        VectorPtr &argToReuse,
        const TypePtr &resultType = VARCHAR());

    /// Return the string encoding of a vector, if not set UTF8 is returned
    bool isAscii(BaseVector *vector, const SelectivityVector &rows);

    /// Wrap an input function with the appropriate ascii instantiation.
    /// Func is a struct templated on boolean with a static function
    /// apply. The wrapper will call Func::apply<bool> based on truth value of the
    /// boolean.
    template<template <bool> typename Func>
    struct StringEncodingTemplateWrapper {
        template<typename... Params>
        static void apply(const bool isAscii, Params... args) {
            if (isAscii) {
                Func<true>::apply(args...);
            } else {
                Func<false>::apply(args...);
            }
        }
    };
} // namespace kumo::pollux::functions
